package com.bachongLightNovel.works.service.impl;

import com.alibaba.fastjson2.JSON;
import com.bachongLightNovel.constant.RabbitmqConstant;
import com.bachongLightNovel.constant.RedisConstant;
import com.bachongLightNovel.error.ErrorCodeEnum;
import com.bachongLightNovel.exception.CustomException;
import com.bachongLightNovel.model.dto.works.BrowseDto;
import com.bachongLightNovel.model.pojo.works.Collect;
import com.bachongLightNovel.model.pojo.works.Novel;
import com.bachongLightNovel.model.vo.page.PageVo;
import com.bachongLightNovel.model.vo.works.BrowseVo;
import com.bachongLightNovel.utils.UserInfoUtil;
import com.bachongLightNovel.works.config.RabbitmqConfig;
import com.bachongLightNovel.works.mapper.WorksNovelMapper;
import com.bachongLightNovel.works.service.WorksBrowseService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * @author vermouth
 */

@Service
public class WorksBrowseServiceImpl implements WorksBrowseService {

    @Autowired
    private WorksNovelMapper worksNovelMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 分页查询已发布通过的小说列表集合
     * @param current : 当前页
     * @param size    : 每页显示记录数
     * @param dto     : 请求条件
     * @return Result
     */
    @Override
    public PageVo<BrowseVo> getPassList(Integer current, Integer size, BrowseDto dto) {
        //查询符合要求的数据数量
        Long total=worksNovelMapper.countByStatus((short) 2);
        //根据条件查询数据
        List<Novel> novelList=worksNovelMapper.selectPass((current-1)*size,size,dto);
        //从redis中获取当前用户的收藏集合
        Long userId = UserInfoUtil.getUser().getId();
        String key= RedisConstant.BACHONG_COLLECT+userId;
        Set<String> collectSet = stringRedisTemplate.opsForSet().members(key);
        //封装成要求返回的格式
        List<BrowseVo> voList=new ArrayList<>();
        for (Novel novel : novelList) {
            BrowseVo vo = new BrowseVo();
            BeanUtils.copyProperties(novel,vo);
            //日后补充相应是否收藏相关信息
            if (!CollectionUtils.isEmpty(collectSet) && collectSet.contains(novel.getId().toString())){
                vo.setIsCollect(true);
            }else {
                vo.setIsCollect(false);
            }
            voList.add(vo);
        }
        PageVo<BrowseVo> pageVo = new PageVo<>();
        pageVo.setTotal(total);
        pageVo.setRecords(voList);
        return pageVo;
    }


    /**
     * 更改当前用户的收藏状态
     * @param collect :
     * @param novelId :
     * @return Result
     */
    @Override
    public void updateCollect(Boolean collect, Long novelId) {
        //获取当前用户id，得到key
        Long userId = UserInfoUtil.getUser().getId();
        String key=RedisConstant.BACHONG_COLLECT+userId;
        //得到收藏列表
        Set<String> collectSet = stringRedisTemplate.opsForSet().members(key);
        //判断当前是收藏还是取消收藏
        if (collect){
            //如果是收藏，则加入到相应的redis集合当中
            if (!CollectionUtils.isEmpty(collectSet) && collectSet.contains(novelId.toString())){
                throw new CustomException(ErrorCodeEnum.COLLECT_IS_EXISTS);
            }
            stringRedisTemplate.opsForSet().add(key,novelId.toString());
        }else {
            //如果是取消收藏，则在相应的redis集合中删除元素
            //判断是否在redis列表当中
            if (CollectionUtils.isEmpty(collectSet) || !collectSet.contains(novelId.toString())){
                throw new CustomException(ErrorCodeEnum.COLLECT_IS_NOT_EXISTS);
            }
            stringRedisTemplate.opsForSet().remove(key,novelId.toString());
        }
        //异步通知数据库进行表的相关操作
        Collect coll = new Collect();
        coll.setUserId(userId);
        coll.setNovelId(novelId);
        coll.setIsCollect(collect);
        String json = JSON.toJSONString(coll);
        //发送异步消息
        rabbitTemplate.convertAndSend(RabbitmqConfig.BACHONG_NOVEL_EXCHANGE,
                RabbitmqConstant.BACHONG_NOVEL_COLLECT_KEY,
                json);
    }

    /**
     * 获取当前登录用户的收藏列表
     * @return Result
     */
    @Override
    public List<BrowseVo> getCollects() {
        //从redis当中查询当前登录用户的收藏列表
        Long userId = UserInfoUtil.getUser().getId();
        String key=RedisConstant.BACHONG_COLLECT+userId;
        Set<String> collectSet = stringRedisTemplate.opsForSet().members(key);
        if (CollectionUtils.isEmpty(collectSet)){
            return null;
        }
        //从数据库当中查询id相关的数据
        List<Novel> list=worksNovelMapper.selectByIds(collectSet);
        //设置相应属性
        List<BrowseVo> voList=new ArrayList<>();
        for (Novel novel : list) {
            BrowseVo vo = new BrowseVo();
            BeanUtils.copyProperties(novel,vo);
            vo.setIsCollect(true);
            voList.add(vo);
        }
        return voList;
    }
}
